#!/usr/bin/python -d

import sys 
from PyQt4 import QtCore, QtGui
from moopsUI import Ui_MainWindow
from cpu import cpu
from translator import trans_file

class moopsWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        QtCore.QObject.connect(self.ui.asm2bin, QtCore.SIGNAL("clicked()"), self.translateAsm )
        QtCore.QObject.connect(self.ui.loadELFBtn, QtCore.SIGNAL("clicked()"), self.loadFile )
        QtCore.QObject.connect(self.ui.ExecuteBtn, QtCore.SIGNAL("clicked()"), self.execute_cpu )
        QtCore.QObject.connect(self.ui.InitializeBtn, QtCore.SIGNAL("clicked()"), self.initialize_pc )
        QtCore.QObject.connect(self.ui.StepBtn, QtCore.SIGNAL("clicked()"), self.cpu_step )

    def translateAsm(self):
        asmFile = QtGui.QFileDialog.getOpenFileName(self, 'Open file', './')
        if(asmFile!=''):
            trans_file(asmFile)
            
    def addInstructions(self):
        self.ui.InstructionMemory.clear()
        instructionCount = self.cpu.getInstructionCount()
        for i in range(instructionCount):
            instruction = "0x"+ (hex(self.cpu.getInstruction(int(0x400000+i*4)) ) [2:].zfill(8)).upper()
            pc = " 0x" + (hex(0x400000+i*4)[2:].zfill(8)).upper()
            self.currentInstruction = QtGui.QListWidgetItem( pc + " " + instruction )
            self.ui.InstructionMemory.insertItem(i,self.currentInstruction)

    def loadFile(self):
        elfFile = QtGui.QFileDialog.getOpenFileName(self, 'Open file', './')
        if(elfFile!=''):
            self.cpu.loadBinary(elfFile)
            self.addInstructions()

    def display_registers(self):
        self.registerState = self.cpu.getRegisterState()
        self.k=0
        for i in range(6):
            for j in range(6):
                if (self.k>31):
                    break
                self.currentRegister = QtGui.QTableWidgetItem( ("$r" + str("%02d")%self.k + " 0x" + hex(self.registerState[self.k])[2:].zfill(8)).upper())
                self.ui.registerStatus.setItem(i,j,self.currentRegister)
                self.k = self.k+1

    def initialize_pc(self):
        self.ui.InstructionMemory.clear()
        self.cpu = cpu()
        self.cpu.initializePipeline()
        self.display_registers()

    def executing_instruction(self):
        instruction = self.cpu.getInstruction(self.pc)
        self.ui.executingInstruction.setText(hex(self.pc) + ' ' + hex(instruction))

    def execute_cpu(self):
        self.cpu.fiveStage()
        self.display_registers()
        
    def cpu_step(self):
        self.pc = self.cpu.getPc()
        pcstep = (self.pc & 0x000FFFFF)/4
        self.executing_instruction()
        if(self.ui.InstructionMemory.item(pcstep)):
            self.ui.InstructionMemory.item(pcstep).setSelected(True)
        else:
            self.ui.InstructionMemory.clearSelection()
        self.cpu.fiveStageStep()
        self.display_registers()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    myapp = moopsWindow()     
    myapp.show()
    sys.exit(app.exec_())